<template>
  <div class="select-box" v-clickoutside="handleClose">
    <el-input
        :disabled="isDisabled"
        :size="inputSize"
        ref="reference"
        v-model="selectedLabel"
        suffix-icon="el-icon-arrow-down"
        @focus="inputFocus"
    >
    </el-input>
    <transition name="el-zoom-in-top" @after-leave="doDestroy">
      <DropDown
          ref="popper"
          v-show="visible"
          :tree-data="$attrs['tree-data']"
          :tree-props="$attrs['tree-props']"
          :tree-node-key="$attrs['tree-node-key']"
          @treeNodeClick="treeClick"
          :current-key="selectedKey"
      >
      </DropDown>
    </transition>
  </div>
</template>

<script>
import Emitter from 'element-ui/src/mixins/emitter';
import DropDown from '@/components/TreeSelect/DropDown.vue';
import Clickoutside from 'element-ui/src/utils/clickoutside';
import { valueEquals } from 'element-ui/src/utils/util';

export default {
  name: 'TreeSelect',
  components: { DropDown },
  mixins: [Emitter],
  directives: { Clickoutside },
  model: {
    prop: 'value',
    event: 'change',
  },
  props: {
    value: {
      type: String,
      required: true,
    },
    size: {
      type: String,
      // default: 'medium',
    },
    disabled: {
      type: Boolean,
      default: false,
    },
  },
  inject: {
    elForm: {
      default: '',
    },
    elFormItem: {
      default: '',
    },
  },
  data() {
    return {
      inputWidth: 0,
      selectedKey: '',
      visible: false,
      selectedLabel: '',
      initialInputHeight: 0,
      inputSize: 'medium',
    };
  },
  watch: {
    visible(val) {
      if (!val) {
        this.broadcast('DropDown', 'destroyPopper');
      } else {
        this.broadcast('DropDown', 'updatePopper');
      }
    },
    selectedKey(val, oldVal) {
      if (!valueEquals(val, oldVal)) {
        this.dispatch('ElFormItem', 'el.form.change', val);
      }
    },
    value: {
      handler(val) {
        if (val) {
          this.selectedKey = this.value;
          this.setSelectedLabel();
        } else {
          this.selectedKey = '';
          this.selectedLabel = '';
        }
      },
      immediate: true,
    },
  },
  computed: {
    isDisabled() {
      return this.disabled || (this.elForm || {}).disabled;
    },
  },
  methods: {
    treeClick(node) {
      this.selectedLabel = node[this.$attrs['tree-props'].label];
      this.selectedKey = node[this.$attrs['tree-node-key']];
      document.querySelector('.select-box .el-icon-arrow-down').style.rotate = '';
      this.visible = false;
      this.$emit('change', this.selectedKey);
    },
    inputFocus() {
      if (this.isDisabled) return;
      document.querySelector('.select-box .el-icon-arrow-down').style.rotate = '180deg';
      this.visible = true;
    },
    handleClose() {
      document.querySelector('.select-box .el-icon-arrow-down').style.rotate = '';
      this.selectedKey = this.value;
      this.setSelectedLabel();
      this.visible = false;
    },
    doDestroy() {
      this.$refs.popper && this.$refs.popper.doDestroy();
    },
    setSelectedLabel() {
      const { label, children } = this.$attrs['tree-props'];
      const key = this.$attrs['tree-node-key'];
      const getLabel = (array, value) => {
        if (array.length) {
          for (let i = 0; i < array.length; i++) {
            let item = array[i];
            if (item[key] && item[key] === value) {
              this.selectedLabel = item[label];
              return;
            } else {
              if (item[children]) getLabel(item[children], this.value);
            }
          }
        }
      };
      getLabel(this.$attrs['tree-data'], this.value);
    },
    sizeRender() {
      const reference = this.$refs.reference;
      this.$nextTick(() => {
        if (reference && reference.$el) {
          const sizeMap = {
            medium: 36,
            small: 32,
            mini: 28,
          };
          let size = (this.elFormItem || {}).elFormItemSize || this.size;
          this.inputSize = size;
          this.initialInputHeight = sizeMap[size];
          // document.querySelector('.el-input__inner').style.height = this.initialInputHeight + 'px';
          if (size !== 'medium') {
            document.querySelector('.el-icon-arrow-down').style.lineHeight = this.initialInputHeight + 'px';
          }
          this.inputWidth = reference.$el.getBoundingClientRect().width;
        }
      });
    },
  },
  mounted() {
    this.sizeRender();
  },
};
</script>

<style scoped lang="less">
.select-box {
  .el-input {
    .el-icon-arrow-down {
      transition: all linear 0.5s;
    }
  }
}
</style>
